package com.example.controller;


import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ZipUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.example.common.Result;
import com.example.common.ZipUtils;
import com.example.entity.Book;
import com.example.entity.Params;
import com.example.entity.Student;
import com.example.entity.dto.UserDTO;
import com.example.exception.CustomException;
import com.example.service.BookService;
import com.example.service.StudentService;
import com.example.service.TypeService;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import cn.hutool.core.util.ZipUtil;

@CrossOrigin
@RestController
@RequestMapping("/book")
public class BookController {

    @Resource
    private BookService bookService;

    @Autowired
    private StudentService studentService;

    @Autowired
    private TypeService typeService;

//    private static final String EXPORT_DIR = "D:\\code\\new-sprig-boot\\newspringboot\\2024";
//      private static final String EXPORT_DIR = "D:\\code\\new-sprig-boot\\newspringboot\\2024";
        private static final String EXPORT_DIR_RELATIVE_PATH = "2024";
    @GetMapping("/search")
    public Result findBySearch(Params params) {
        PageInfo<Book> info = bookService.findBySearch(params);
        return Result.success(info);

    }

    @GetMapping("/searchExport")
    public Result findBySearchExport(Params params) {
        PageInfo<Book> info = bookService.findBysearchExport(params);
        return Result.success(info);
    }
    @GetMapping("/searchNotExport")
    public Result findBySearchNotExport(Params params) {
        PageInfo<Book> info = bookService.findBySearchNotExport(params);
        return Result.success(info);
    }

    @PostMapping
    public Result save(@RequestBody UserDTO userDTO) {


        if (userDTO.getImg().length() == 0 ){
            return Result.error("图片未上传");
        }
        String s = userDTO.getImg().split("\\.")[0];
        String  studentName = s.substring(8);
        if (!userDTO.getName().equals(studentName) ){
            return Result.error("图片命名错误");
        }


        //根据姓名考号身份证在学生表中查找是否存在该学生
//         userDTO.setPhoto(BaseContext.getCurrentId());
        Student student = studentService.getBy(userDTO);
//        if (student == null) {
//            return Result.error("该学生不存在");
//        } else if (student.getCount() >= 2) {
//            return Result.error("已经修改两次了，不能再修改了");
//        }

        if (student == null) {
            return Result.error("该学生不存在");
        }
//        String number = typeService.selectNumberByIdCard(student.getIdCard());
          Integer count = bookService.selectCountByidcard(student.getIdCard());

        /*
         * 第一次提交，提交状态修改为1（表示已经提交），然后增加修改次数
         * 注意：这里还得补充
         * 第二次提交，增加修改次数
         * */
        if (count==null) {
//            bookService.add(userDTO);

              bookService.addStudent(userDTO);
//              typeService.updateStatus(userDTO);
//              studentService.updataCount(userDTO);
        } else if(count==1){
//            bookService.update(userDTO);

//            typeService.updateStatus(userDTO);
              bookService.updateStudent(userDTO);
//              studentService.updataCount(userDTO);
        } else {
            return Result.error("已经修改两次了，不能再修改了");
        }
        return Result.success();
    }

    //
    @GetMapping("/fillnumber")
    public Result fillNumber() {
         return bookService.fill();

    }
    @GetMapping("/export")
    public ResponseEntity export(HttpServletResponse response) throws IOException {




        // 1. 生成 Excel 文件的字节数组
        byte[] excelBytes = generateExcel();

        // 2. 下载指定文件夹下的所有文件并打包成 zip，返回 zip 文件路径
        Path zipFilePath = downloadAndZipFolder();

        // 3. 合并两个下载内容并提供响应
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        headers.setContentDispositionFormData("attachment", "download.zip");

        // 将 Excel 文件和 ZIP 文件内容合并到一个 ZIP 文件中
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try (ZipOutputStream zos = new ZipOutputStream(baos)) {
            // 添加 Excel 文件到 ZIP
            ZipEntry excelEntry = new ZipEntry("idCard.xlsx");
            zos.putNextEntry(excelEntry);
            zos.write(excelBytes);
            zos.closeEntry();

            // 添加指定文件夹下的所有文件到 ZIP
            byte[] zipBytes = Files.readAllBytes(zipFilePath);
            ZipEntry folderEntry = new ZipEntry("exportedFiles.zip");
            zos.putNextEntry(folderEntry);
            zos.write(zipBytes);
            zos.closeEntry();
        }

        // 设置响应体
        byte[] zipFileBytes = baos.toByteArray();
        return ResponseEntity.ok()
                .headers(headers)
                .contentType(MediaType.APPLICATION_OCTET_STREAM)
                .contentLength(zipFileBytes.length)
                .body(zipFileBytes);
    }

    // 生成 Excel 文件并返回其字节数组
    private byte[] generateExcel() throws IOException {
        // 从数据库中查询所有数据
        List<Book> all = bookService.findAll();

        if (all.isEmpty()) {
            throw new RuntimeException("未找到数据");
        }

        // 定义一个 List，存储处理之后的数据，用于塞到 list 里
        List<Map<String, Object>> list = new ArrayList<>(all.size());

        // 遍历每一条数据，封装到 Map<key,value> 里，把这个 map 塞到 list 里
        for (Book book : all) {
            Map<String, Object> row = new HashMap<>();
            row.put("姓名", book.getName());
            row.put("学号", book.getNumber());
            row.put("学院", book.getCollege());
            row.put("专业", book.getMajor());
            row.put("照片", book.getPhoto());

            list.add(row);
        }

        // 创建一个 ExcelWriter，把 list 数据用这个 writer 写出来（生成出来）
        ExcelWriter wr = ExcelUtil.getWriter(true);
        wr.write(list, true);

        // 将 Excel 写入字节数组
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        wr.flush(out, true);
        wr.close();
        IoUtil.close(System.out);

        return out.toByteArray();
    }

    // 下载指定文件夹下的所有文件并打包成 zip，返回 zip 文件路径
    private Path downloadAndZipFolder() throws IOException {
        String currentWorkingDir = System.getProperty("user.dir");
        String exportDirPath = Paths.get(currentWorkingDir, EXPORT_DIR_RELATIVE_PATH).toString();
        // 检查指定的导出目录是否存在
        File exportDir = new File(exportDirPath);
        if (!exportDir.exists() || !exportDir.isDirectory()) {
            throw new RuntimeException("指定的导出目录不存在或不是一个有效的目录。");
        }

        // 打包整个目录为压缩文件
        Path zipFile = Files.createTempFile("export", ".zip");
        ZipUtil.zip(exportDir.getAbsolutePath(), String.valueOf(zipFile.toFile()), true);
        return zipFile;
    }


}
